package cn.jbolt.wechat.api.interceptor;

import cn.hutool.core.util.StrUtil;
import cn.jbolt.wechat.api.JBoltWechatMaMsgController;
import cn.jbolt.wechat.api.JBoltWechatMpMsgController;
import cn.jbolt.wechat.common.miniapp.WechatMaContext;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.core.Controller;
import com.jfinal.kit.StrKit;
import com.jfinal.log.Log;

public class WechatMaMsgInterceptor implements Interceptor {
    private static final Log log = Log.getLog(WechatMaMsgInterceptor.class);

    private static final String DEFAULT_APP_ID_KEY = "appId";



    @Override
    public void intercept(Invocation inv) {
        Controller controller = inv.getController();
        if (!(controller instanceof JBoltWechatMaMsgController)) {
            throw new RuntimeException("控制器需要继承 JBoltWechatMsgController");
        }
        try {
            String appId = controller.getPara(DEFAULT_APP_ID_KEY);
            if (StrUtil.isBlank(appId)) {
                log.error("从url中未获取到appId，无法处理该请求");
                controller.renderText("");
            }
            // 将 appId 与当前线程绑定，以便在后续操作中方便获取ApiConfig对象： ApiConfigKit.getApiConfig();
            WechatMaContext.switchTo(appId);

            // 如果是服务器配置请求，则配置服务器并返回
            if (isConfigServerRequest(controller)) {
                configServer(controller);
                return;
            }

            // 签名检测
            if (checkSignature(controller)) {
                inv.invoke();
            } else {
                log.error("签名验证失败，请确定是微信服务器在发送消息过来");
                controller.renderText("");
            }

        } finally {
            WechatMaContext.switchOver();
        }
    }

    /**
     * 检测签名
     */
    private boolean checkSignature(Controller controller) {
        String signature = controller.getPara("signature");
        String timestamp = controller.getPara("timestamp");
        String nonce = controller.getPara("nonce");
        if (StrKit.isBlank(signature) || StrKit.isBlank(timestamp) || StrKit.isBlank(nonce)) {
            controller.renderText("check signature failure");
            return false;
        }

        if (WechatMaContext.checkSignature(timestamp, nonce, signature)) {
            return true;
        } else {
            log.error("check signature failure: " +
                    " signature = " + controller.getPara("signature") +
                    " timestamp = " + controller.getPara("timestamp") +
                    " nonce = " + controller.getPara("nonce"));

            return false;
        }
    }

    /**
     * 是否为开发者中心保存服务器配置的请求
     */
    private boolean isConfigServerRequest(Controller controller) {
        return StrKit.notBlank(controller.getPara("echostr"));
    }

    /**
     * 配置开发者中心微信服务器所需的 url 与 token
     *
     * @param c 控制器
     */
    public void configServer(Controller c) {
        // 通过 echostr 判断请求是否为配置微信服务器回调所需的 url 与 token
        String echostr = c.getPara("echostr");
        String signature = c.getPara("signature");
        String timestamp = c.getPara("timestamp");
        String nonce = c.getPara("nonce");
        boolean isOk = WechatMaContext.checkSignature(timestamp, nonce, signature);
        if (isOk) {
            c.renderText(echostr);
        } else {
            log.error("验证失败：configServer");
        }
    }
}